package com.jxmcloud.business.cut.service.impl.admin.activity;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jxmcloud.business.cut.constants.CutErrorMsg;
import com.jxmcloud.business.cut.constants.CutSaveKey;
import com.jxmcloud.business.cut.dto.admin.GmUserWatchLiveTaskDetailDto;
import com.jxmcloud.business.cut.dto.gm.AddInvitedDto;
import com.jxmcloud.business.cut.dto.gm.KickOffDto;
import com.jxmcloud.business.cut.dto.gm.ResetActivityIdDto;
import com.jxmcloud.business.cut.dto.gm.UpdateProgressDto;
import com.jxmcloud.business.cut.dtoCommon.EServerNoticeTypeDto;
import com.jxmcloud.business.cut.enums.UserStatus;
import com.jxmcloud.business.cut.json.DataConfigActivityStartLoader;
import com.jxmcloud.business.cut.json.DataConfigService;
import com.jxmcloud.business.cut.json.DataConfigStartLoader;
import com.jxmcloud.business.cut.mapper.database.IRefreshConfigLogDBMapper;
import com.jxmcloud.business.cut.mapper.database.IUserActivityInfoDBMapper;
import com.jxmcloud.business.cut.mapper.database.IUserWatchLiveTaskDetailDBMapper;
import com.jxmcloud.business.cut.model.activity.Bag;
import com.jxmcloud.business.cut.model.database.*;
import com.jxmcloud.business.cut.model.json.ConfigActivityStart;
import com.jxmcloud.business.cut.model.json.ConfigActivityTask;
import com.jxmcloud.business.cut.model.json.ConfigItem;
import com.jxmcloud.business.cut.model.json.ConfigStart;
import com.jxmcloud.business.cut.service.admin.activity.IGmService;
import com.jxmcloud.business.cut.service.database.*;
import com.jxmcloud.business.cut.service.json.*;
import com.jxmcloud.business.cut.service.logic.IGmOperatorHandle;
import com.jxmcloud.business.cut.service.logic.IUserLiveHandle;
import com.jxmcloud.business.cut.service.user.*;
import com.jxmcloud.business.cut.util.MyTool;
import com.jxmcloud.business.cut.vo.*;
import com.jxmcloud.business.cut.vo.json.*;
import com.jxmcloud.business.cut.vo.user.PlayerInfoVo;
import com.jxmcloud.business.cut.vo.user.UserActivityVo;
import com.jxmcloud.business.cut.vo.user.UserFlowVo;
import com.xlcloud.platform.api.exception.BusinessException;
import com.xlcloud.platform.util.DateUtil;
import com.xxl.sso.core.login.SsoTokenLoginHelper;
import com.xxl.sso.core.user.XxlSsoUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.time.LocalDateTime;

@Service
@Slf4j
public class GmServiceImpl implements IGmService {
    @Resource
    private IUserManagerService userManagerService;
    @Resource
    private IUserFlowService userFlowService;
    @Resource
    private IUserActivityService userActivityService;
    @Resource
    private DataConfigService dataConfigService;
    @Resource
    private IUserActivityInfoDBService userActivityDBService;
    @Resource
    private IUserCashDetailListService userCashDetailListService;
    @Resource
    private IUserDrawTurnService userDrawTurnService;
    @Resource
    private IUserBagDBService userBagDBService;
    @Resource
    private IConfigItemService configItemService;
    @Resource
    private IRefreshConfigLogDBMapper refreshConfigLogDBMapper;
    @Resource
    private IConfigActivityStartService configActivityStartService;
    @Resource
    private IUserLoginInfoService userLoginInfoService;
    @Resource
    private IConfigStartService configStartService;
    @Resource
    private IUserLoginInfoDBService userLoginInfoDBService;
    @Resource
    private IUserFlowDBService userFlowDBService;
    @Resource
    private IConfigProgressService configProgressService;
    @Resource
    private IUserWatchLiveTaskDetailDBMapper userWatchLiveTaskDetailMapper;
    @Autowired
    private IGmOperatorHandle gmOperatorHandle;
    @Autowired
    private IUserProgressLogDBService userProgressLogDBService;
    @Autowired
    private IUserLiveHandle userLiveHandle;
    @Resource
    private IUserActivityInfoDBMapper userActivityInfoDBMapper;
    @Resource
    private IConfigActivityTaskService configActivityTaskService;
    @Resource
    private DataConfigStartLoader dataConfigStartLoader;
    @Override
    public void updateProgress(UpdateProgressDto updateProgressDto) {
        String error = CutErrorMsg.ERROR_TRUE;
        boolean isContinue = true;
        //目的步骤
        Integer progressId = updateProgressDto.getProgressId();
        if (ObjectUtil.isNull(progressId) || progressId.equals(0)) {
            error = "进度ID不能为空";
        }
        String account = updateProgressDto.getAccount();
        if (ObjectUtil.isNull(account) || account.isEmpty()) {
            error = "账号不能为空";
        }

        PlayerInfoVo player = userManagerService.getUserInfoByAccount(account);
        if (Objects.isNull(player)) {
            throw new BusinessException("请先登录游戏");
        }
        UserFlowVo flowInfo = player.getFlowInfo();
        //用户当前步骤id
        Integer stepId = flowInfo.getStepId();
        if (Objects.equals(stepId, progressId)) {
            error = "输入的步骤为当前步，请重新输入";
        }
        //缓存递归查询目的流程在当前步骤的前还是后
        boolean stepAhead = isStepAhead(stepId, progressId, player);//目的步骤在当前步骤后面;
        boolean stepAfter = isStepAhead(progressId, stepId, player);//目的步骤在当前步骤前面;
        if (!stepAhead && !stepAfter) {
            throw new BusinessException("输入的步骤不在当前步骤前后");
        }

        do {
            //如果没有到达目的步骤一直循环
            if (!Objects.equals(stepId, progressId)) {
                // 是否执行了事件
                if (stepAhead) {
                    //查询当前步骤的启动事件
                    ConfigProgressVo progressConfig = dataConfigService.getConfigProgressConfig(stepId);
                    if (Objects.isNull(progressConfig) || Objects.isNull(progressConfig.getStartEvent())) {
                        error = "用户当前步骤有误";
                    }
                    List<Integer> startEvents = Arrays.asList(progressConfig.getStartEvent());
                    boolean anyEventProcessed = false; // 添加标志变量跟踪是否有事件被成功处理避免死循环
                    for (Integer startEvent : startEvents) {
                        // 判断事件是否有效
                        boolean checkFlag = userFlowService.checkEventValid(player, stepId, startEvent);
                        if (!checkFlag) {
                            // 无效事件
                            continue;
                        }
                        // 条件判断
                        checkFlag = userFlowService.checkFlowEvent(player, startEvent);
                        if (!checkFlag) {
                            // 无效事件
                            continue;
                        }

                        // 执行事件
                        boolean flag = userFlowService.runEvent(player, startEvent);
                        if (!flag) {
                            continue;
                        }
                        // 在runEvent已经将当前步骤设置为下一步
                        stepId = player.getFlowInfo().getStepId();
                        anyEventProcessed = true; // 标记至少有一个事件被成功处理
                        break;
                    }
                    // 循环结束后检查是否有任何事件被成功处理
                    if (!anyEventProcessed) {
                        // 所有事件都无效或失败，抛出异常
                        throw new BusinessException("当前步骤所有事件都无效或执行失败，无法继续流程");
                    }
                } else {
                    //查询当前步骤的启动事件
                    ConfigProgressVo progressConfig = dataConfigService.getConfigProgressConfig(progressId);
                    if (Objects.isNull(progressConfig) || Objects.isNull(progressConfig.getStartEvent())) {
                        error = "用户当前步骤有误";
                    }
                    List<Integer> startEvents = Arrays.asList(progressConfig.getStartEvent());
                    boolean anyEventProcessed = false; // 添加标志变量跟踪是否有事件被成功处理避免死循环
                    for (Integer startEvent : startEvents) {
                        //校验当前事件的
                        // 判断事件是否有效
                        boolean checkFlag = userFlowService.checkEventValid(player, stepId, startEvent);
                        if (!checkFlag) {
                            // 无效事件
                            continue;
                        }
                        // 条件判断
                        checkFlag = userFlowService.checkFlowEvent(player, startEvent);
                        if (!checkFlag) {
                            // 无效事件
                            continue;
                        }

                        // 执行事件
                        boolean flag = userFlowService.revertRunEvent(player, startEvent);
                        if (!flag) {
                            continue;
                        }
                        // 在runEvent已经将当前步骤设置为下一步
                        progressId = player.getFlowInfo().getStepId();
                        anyEventProcessed = true; // 标记至少有一个事件被成功处理
                        break;
                    }
                    // 循环结束后检查是否有任何事件被成功处理
                    if (!anyEventProcessed) {
                        // 所有事件都无效或失败，抛出异常
                        throw new BusinessException("当前步骤所有事件都无效或执行失败，无法继续流程");
                    }
                }

                // 刷新缓存信息
                userManagerService.refreshPlayerCache(player);
            } else {
                //到达目的步骤
                isContinue = false;
            }
        } while (isContinue);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
    }

    @Override
    public void updateProgressNew(UpdateProgressDto updateProgressDto) {
        String error = CutErrorMsg.ERROR_TRUE;
        ProgressVo progressVo;
        PlayerInfoVo player = userManagerService.getUserInfoByAccount(updateProgressDto.getAccount());
        if (Objects.isNull(player)) {
            throw new BusinessException("请先登录游戏");
        }

        do {
            // 1. 校验请求参数信息
            boolean flag = gmOperatorHandle.checkProcessParam(updateProgressDto,player);
            if (!flag) {
                error = "请求参数有误";
                break;
            }
            // 2. 校验设置的当前步骤是否有效
            ConfigProgressVo progressConfig = dataConfigService.getConfigProgressConfig(updateProgressDto.getProgressId());
            if (ObjectUtil.isNull(progressConfig)) {
                error = "当前设置的流程有误";
                break;
            }

            // 3. 删除或者新增流程用户获取奖励信息
            List<DBUserProgressLog> userProgressLogByStepId = userProgressLogDBService.getUserProgressLogByStepId(player.getBase().getUid(),
                    player.getActivity().getActivityId(),
                    updateProgressDto.getProgressId());
            if(userProgressLogByStepId.isEmpty()) {
                // 设置流程在后面
                // progressVo = gmOperatorHandle.handProgressAfter(updateProgressDto.getProgressId(), player);
                progressVo = new ProgressVo();
                progressVo.setStepId(updateProgressDto.getProgressId());
            } else {
                // 设置流程在前面
                progressVo = gmOperatorHandle.handProgressBefore(userProgressLogByStepId, updateProgressDto.getProgressId(), player);
            }

            // 设置用户流程ID
            UserFlowVo flowInfo = player.getFlowInfo();
            flowInfo.setStepId(progressVo.getStepId());
            flowInfo.setPreId(progressVo.getPreStepId());

            // 刷新用户信息
            player.getMaster().getSaveList().add(CutSaveKey.USER_FLOW);

            // 刷新缓存信息
            userManagerService.refreshPlayerCache(player);
        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
    }

    public boolean isStepAhead(int stepId, int progressId,PlayerInfoVo player) {
        // 获取当前步骤的配置
        ConfigProgressVo configProgressConfig = dataConfigService.getConfigProgressConfig(stepId);
        Integer[] startEvents = configProgressConfig.getStartEvent();
        if (Objects.isNull(startEvents)) {
            return false;
        }

        int preStepId = 0;

        // 遍历当前步骤的所有事件
        for (Integer startEvent : startEvents) {
            // 校验当前事件是否有效
            boolean checkFlag = userFlowService.checkEventValid(player, stepId, startEvent);
            if (!checkFlag) {
                continue; // 无效事件跳过
            }

            // 校验事件流程是否有效
            checkFlag = userFlowService.checkFlowEvent(player, startEvent);
            if (!checkFlag) {
                continue; // 无效事件跳过
            }

            // 获取当前事件配置
            ConfigEventVo eventConfig = dataConfigService.getConfigEventConfig(startEvent);
            if (ObjectUtil.isNull(eventConfig)) {
                throw new BusinessException("事件查询失败");
            }

            // 获取当前事件的下一步步骤
            preStepId = eventConfig.getProgressId();

        }
        //没有下一个步骤
        if (preStepId == 0) {
            throw new BusinessException("下一个步骤查询失败");
        }

        if (preStepId == stepId) {
            return false;
        }
        // 如果当前步骤不是目标步骤，递归查找下一步
        if (preStepId != progressId) {
            return isStepAhead(preStepId, progressId,player);
        }

        // 如果下一步是目标步骤，则返回true，表示目标步骤在当前步骤的后面
        if (preStepId == progressId) {
            return true;
        }

        // 如果遍历完所有事件都没有找到目标步骤，返回false，表示目标步骤在当前步骤的前面
        return false;
    }

    public boolean runEvent(PlayerInfoVo player, Integer progressId) {
        return this.enterNextProgress(player, progressId);
    }

    public boolean enterNextProgress(PlayerInfoVo player, Integer progressId) {
        UserFlowVo flowInfo = player.getFlowInfo();
        Integer oldProgressId = flowInfo.getStepId();
        ConfigProgressVo progressConfig = dataConfigService.getConfigProgressConfig(progressId);
        if (ObjectUtil.isNull(progressConfig)) {
            return false;
        }
        flowInfo.setPreId(oldProgressId);
        flowInfo.setStepId(progressId);
        // 判断是否有触发标题  没有触发标题就是实物
        if (ObjectUtil.isNull(progressConfig.getOrderTrans())) {
            // 回滚创建订单
            userCashDetailListService.revertMakeCashDetailByProgressId(player, progressId);
        } else {
            userCashDetailListService.revertMakeOrderCashDetailByProgressId(player, progressId);
        }
        // 检测轮盘初始化
        userDrawTurnService.checkTurnRelease(player, progressConfig.getRoundType());
        player.getMaster().getSaveList().add(CutSaveKey.USER_FLOW);
        return true;
    }


    @Override
    public void checkAddInvitedPlayer(AddInvitedDto addInvitedDto) {
        String error = CutErrorMsg.ERROR_TRUE;
        do {
            String helperAccount = addInvitedDto.getNewAccount();
            String account = addInvitedDto.getAccount();
            Boolean isNew = addInvitedDto.getIsNew();
            if (helperAccount.equals(account)) {
                error = "不能邀请自己";
                break;
            }

            PlayerInfoVo helper = userManagerService.getUserInfoByAccount(helperAccount);
            if (Objects.isNull(helper)) {
                error = "需助力用户登录一次游戏";
                break;
            }

            // 自己
            PlayerInfoVo player = userManagerService.getUserInfoByAccount(account);
            if (Objects.isNull(player)) {
                error = "需被助力用户登录游戏";
                break;
            }
            Integer userType = isNew ? 1 : 0;
            userActivityService.checkAddInvitedPlayer(helper, player.getBase().getUid(), player.getActivity().getActivityId(), userType);
        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetActivityId(ResetActivityIdDto resetActivityIdDto) {
        String error = CutErrorMsg.ERROR_TRUE;
        do {
            PlayerInfoVo player = userManagerService.getUserInfoByAccount(resetActivityIdDto.getAccount());
            if (Objects.isNull(player)) {
                error = "请先登录游戏";
                break;
            }

            ConfigStartVo configStart = dataConfigService.getConfigStartConfig(resetActivityIdDto.getNewStartId());
            if (ObjectUtil.isNull(configStart)) {
                error = "开局活动配置不存在";
                break;
            }

            //
            Integer oldActivityId = player.getActivity().getActivityId();
            Integer newActivityId = configStart.getActivityId();

            // 更新活动
            UserActivityVo activity = player.getActivity();
            activity.setActivityId(newActivityId);
            activity.setStartId(resetActivityIdDto.getNewStartId());
            userFlowService.refreshFlowData(player);

            // 同一个活动重置
            boolean isNew = !oldActivityId.equals(newActivityId);
            boolean dealResult = this.updateUserActivityDB(player, isNew);
            if (!dealResult) {
                error = "活动数据数据库处理失败";
                break;
            }
            // 刷新缓存信息
            userManagerService.refreshPlayerCache(player);
        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
    }

    private boolean updateUserActivityDB(PlayerInfoVo player, boolean isNew) {
        Date nowTime = new Date();
        DBUserActivityInfo dbData = DBUserActivityInfo.builder().build();
        dbData.setUid(player.getBase().getUid());
        dbData.setActivityId(player.getActivity().getActivityId());
        dbData.setActivityStartId(player.getActivity().getStartId());
        dbData.setWatchLive(0);
        dbData.setGainPrize(0);
        dbData.setStatus(0);
        dbData.setNewUserCount(0);
        dbData.setCreateTime(nowTime);
        dbData.setBeganTime(nowTime);
        if (isNew) {
            // 插入一条新的活动数据
            return userActivityDBService.insertIntoData(dbData);
        } else {
            //更新
            return userActivityDBService.updateData(dbData);
        }
    }

    @Override
    public void kickOff(KickOffDto kickOffDto) {
        String error = CutErrorMsg.ERROR_TRUE;
        do {
            PlayerInfoVo player = userManagerService.getUserInfoByAccount(kickOffDto.getAccount());
            if (Objects.isNull(player)) {
                error = "用户信息不存在";
                break;
            }

            player.getBase().setStatus(UserStatus.KICKED_OUT.getValue());
            userActivityService.addNoticeType(player, EServerNoticeTypeDto.KICK_OFF);

            // 刷新缓存信息
            userManagerService.refreshPlayerCache(player);

        } while (false);
        if (!error.equals(CutErrorMsg.ERROR_TRUE)) {
            // 抛出异常
            throw new BusinessException(error);
        }
    }

    @Override
    public List<Bag> getUserConfigItem(String account) {
        if (Objects.isNull(account)) {
            return Collections.emptyList();
        }
        //根据玄乐账号获取用户id
        LambdaQueryWrapper<DBUserLoginInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DBUserLoginInfo::getAccount, account);
        DBUserLoginInfo userInfo = userLoginInfoService.getOne(queryWrapper);

        if (Objects.isNull(userInfo)) {
            throw new BusinessException("账户不存在，请重新输入");
        }

        // 先获取所有的配置道具项
        List<ConfigItem> allConfigItems = configItemService.list();

        // 创建一个map存储用户背包中的道具，键为道具ID，值为数量
        Map<Integer, Integer> userItemMap = new HashMap<>();

        // 获取用户背包
        DBUserBag dbUserBag = userBagDBService.loadBag(userInfo.getUid());
        if (dbUserBag != null && !StringUtils.isEmpty(dbUserBag.getBag()) && !dbUserBag.getBag().equals("[]")) {
            try {
                // 使用Jackson解析JSON字符串为列表
                ObjectMapper mapper = new ObjectMapper();
                List<Map<String, Integer>> bagItems = mapper.readValue(dbUserBag.getBag(),
                        new TypeReference<List<Map<String, Integer>>>() {});

                // 将用户背包中的道具放入map
                for (Map<String, Integer> item : bagItems) {
                    Integer k = item.get("k");
                    Integer v = item.get("v");
                    userItemMap.put(k, v);
                }
            } catch (Exception e) {
                log.error("解析用户背包数据失败", e);
            }
        }

        // 构建结果列表，包含所有配置道具
        List<Bag> result = new ArrayList<>();
        for (ConfigItem configItem : allConfigItems) {
            Bag bag = new Bag();
            bag.setK(configItem.getId());
            // 如果用户背包中有该道具，设置实际数量；否则设置为0
            bag.setV(userItemMap.getOrDefault(configItem.getId(), 0));
            bag.setName(configItem.getName());
            result.add(bag);
        }
        return result;
    }

    @Override
    public IPage<RefreshConfigLogVo> getRefreshConfigLog(Integer pageNum, Integer pageSize) {
        //获取当前登陆人id
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attr.getRequest();
        XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(request.getHeader("xxl_sso_sessionid"));
        if(xxlUser == null){
            throw new BusinessException("登录超时，请重新登录");
        }

        // 创建分页对象
        Page<DBRefreshConfigLog> page = new Page<>(pageNum, pageSize);

        QueryWrapper<DBRefreshConfigLog> wrapper = new QueryWrapper<>();
        // 计算一个月前的时间
        LocalDateTime oneMonthAgo = LocalDateTime.now().minusMonths(1);
        // 使用ge(大于等于)过滤出一个月内的数据
        wrapper.ge("refresh_time", oneMonthAgo);
        // 使用分页查询
        IPage<DBRefreshConfigLog> refreshConfigLogIPage = refreshConfigLogDBMapper.selectPage(page, wrapper);

        List<RefreshConfigLogVo> refreshConfigLogVos = refreshConfigLogIPage.getRecords().stream().map(dbRefreshConfigLog -> {
            RefreshConfigLogVo refreshConfigLogVo = new RefreshConfigLogVo();
            refreshConfigLogVo.setStatus(dbRefreshConfigLog.getStatus());
            System.out.println("Original refreshTime: " + dbRefreshConfigLog.getRefreshTime().getTime());
            refreshConfigLogVo.setRefreshTime(MyTool.getCurrentTimeSecond(dbRefreshConfigLog.getRefreshTime().getTime()));
            refreshConfigLogVo.setOperateName(dbRefreshConfigLog.getOperateName());
            return refreshConfigLogVo;
        }).collect(Collectors.toList());

        // 构建分页结果
        Page<RefreshConfigLogVo> result = new Page<>();
        result.setRecords(refreshConfigLogVos);
        result.setTotal(refreshConfigLogIPage.getTotal());
        result.setCurrent(refreshConfigLogIPage.getCurrent());
        result.setSize(refreshConfigLogIPage.getSize());

        return result;
    }

    @Override
    public IPage<GmConfigActivityStartVo> getResetActivity(Integer pageNum, Integer pageSize) {
        // 分页参数
        Page<ConfigActivityStart> activityPage = new Page<>(pageNum, pageSize);
        // 获取当前日期字符串，格式为"yyyy-MM-dd"
        String currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());

        QueryWrapper<ConfigActivityStart> queryWrapper = new QueryWrapper<>();

        // 开始时间小于等于当前时间（开始时间 <= 当前时间）
        queryWrapper.le("start_time", currentDate);

        // 结束时间为空或大于等于当前时间（结束时间 >= 当前时间 或 结束时间为空）
        queryWrapper.and(wrapper -> wrapper.ge("end_time", currentDate).or().isNull("end_time"));

        // 执行查询
        IPage<ConfigActivityStart> activityPageResult  = configActivityStartService.getBaseMapper().selectPage(activityPage,queryWrapper);

        if (activityPageResult.getRecords().isEmpty()) {
            return new Page<>();
        }

        // 获取所有活动ID
        List<Integer> activityIds = activityPageResult.getRecords().stream()
                .map(ConfigActivityStart::getId)
                .collect(Collectors.toList());

        // 查询对应的ConfigStart数据
        QueryWrapper<ConfigStart> configStartQueryWrapper = new QueryWrapper<>();
        configStartQueryWrapper.in("activity_id", activityIds);
        List<ConfigStart> configStarts = configStartService.getBaseMapper().selectList(configStartQueryWrapper);

        // 创建活动ID到ConfigStart列表的映射
        Map<Integer, List<ConfigStart>> activityToStartsMap = configStarts.stream()
                .collect(Collectors.groupingBy(ConfigStart::getActivityId));

        List<GmConfigActivityStartVo> resultList = new ArrayList<>();

        // 处理所有活动
        for (ConfigActivityStart activity : activityPageResult.getRecords()) {
            // 获取该活动的所有ConfigStart记录
            List<ConfigStart> starts = activityToStartsMap.getOrDefault(activity.getId(), new ArrayList<>());

            if (starts.isEmpty()) {
                // 如果该活动没有ConfigStart记录，添加一个gold为null的记录
                GmConfigActivityStartVo vo = new GmConfigActivityStartVo();
                vo.setGold(null);
                vo.setStartTime(activity.getStartTime());
                vo.setEndTime(activity.getEndTime());
                vo.setId(activity.getId());
                resultList.add(vo);
            } else {
                // 如果有ConfigStart记录，为每个不同的gold值创建一个记录
                // 使用Set收集不同的gold值
                Set<Integer> uniqueGoldValues = starts.stream()
                        .map(ConfigStart::getGold)
                        .collect(Collectors.toSet());
                for (Integer goldValue : uniqueGoldValues) {
                    GmConfigActivityStartVo vo = new GmConfigActivityStartVo();
                    vo.setGold(goldValue);
                    vo.setStartTime(activity.getStartTime());
                    vo.setEndTime(activity.getEndTime());
                    vo.setId(activity.getId());
                    resultList.add(vo);
                }
            }
        }

        // 构建分页结果
        Page<GmConfigActivityStartVo> result = new Page<>();
        result.setRecords(resultList);
        result.setTotal(activityPageResult.getTotal());
        result.setCurrent(activityPageResult.getCurrent());
        result.setSize(activityPageResult.getSize());
        return result;
    }

    @Override
    public GmUserLoginInfoVo getUserList(String account) {
        if (StringUtils.isEmpty(account)) {
            return null;
        }
        DBUserLoginInfo dbUserLoginInfos = userLoginInfoDBService.getUserList(account);
        if (Objects.isNull(dbUserLoginInfos)) {
            return null;
        }
        GmUserLoginInfoVo gmUserLoginInfoVo = new GmUserLoginInfoVo();
        BeanUtils.copyProperties(dbUserLoginInfos, gmUserLoginInfoVo);
        //查询用户当前活动
        DBUserActivityInfo dbUserActivityInfo = userActivityDBService.selectAllByUid(dbUserLoginInfos.getUid()).get(0);
        gmUserLoginInfoVo.setActivityId(dbUserActivityInfo.getActivityId());
        //查询用户当前步骤
        DBUserFlowInfo dbUserFlowInfo = userFlowDBService.selectOne(dbUserLoginInfos.getUid(), dbUserActivityInfo.getActivityId());
        if (Objects.isNull(dbUserFlowInfo)) {
            return null;
        }
        //查询用户下一步步骤
        PlayerInfoVo player = userManagerService.getUserInfoByAccount(account);
        Integer stepId = dbUserFlowInfo.getStepId();
        if (Objects.isNull(player)) {
            throw new BusinessException("请先登录游戏");
        }
        ConfigProgressVo configProgressConfig = dataConfigService.getConfigProgressConfig(stepId);
        Integer[] startEvents = configProgressConfig.getStartEvent();

        int nextStepId = 0;

        if (startEvents != null && startEvents.length != 0) {
        // 遍历当前步骤的所有事件
        for (Integer startEvent : startEvents) {
            // 校验当前事件是否有效
            boolean checkFlag = userFlowService.checkEventValid(player, stepId, startEvent);
            if (!checkFlag) {
                continue; // 无效事件跳过
            }

            // 校验事件流程是否有效
            checkFlag = userFlowService.checkFlowEvent(player, startEvent);
            if (!checkFlag) {
                continue; // 无效事件跳过
            }

            // 获取当前事件配置
            ConfigEventVo eventConfig = dataConfigService.getConfigEventConfig(startEvent);
            if (ObjectUtil.isNull(eventConfig)) {
                throw new BusinessException("事件查询失败");
            }

            // 获取当前事件的下一步步骤
            nextStepId = player.getFlowInfo().getStepId();
            }
        }
        gmUserLoginInfoVo.setStepId(dbUserFlowInfo.getStepId());
        gmUserLoginInfoVo.setNextStepId(nextStepId);
        return gmUserLoginInfoVo;
    }

    @Override
    public GmWatchLiveConfigActivityTaskVo getWatchLiveTaskList(String account) {
        //查询uid
        if (StringUtils.isEmpty(account)) {
            return null;
        }
        //根据玄乐账号获取用户id
        LambdaQueryWrapper<DBUserLoginInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DBUserLoginInfo::getAccount, account);
        DBUserLoginInfo userInfo = userLoginInfoService.getOne(queryWrapper);
        if (Objects.isNull(userInfo)) {
            return null;
        }
        QueryWrapper<DBUserWatchLiveTaskDetail> DBUserWatchQueryWrapper = new QueryWrapper<>();
        List<DBUserWatchLiveTaskDetail> userWatchTaskList = userWatchLiveTaskDetailMapper.selectList(DBUserWatchQueryWrapper.eq("uid", userInfo.getUid()));
        if (CollectionUtils.isEmpty(userWatchTaskList)) {
            return null;
        }
        //查询任务
        userWatchTaskList.sort(Comparator.comparing(DBUserWatchLiveTaskDetail::getCreateTime));
        // 观看直播开始时间
        String startDay = DateUtil.formatDate(userWatchTaskList.get(0).getCreateTime());
        // 当前时间
        String endDay = DateUtil.formatDate(new Date());
        PlayerInfoVo player = userManagerService.getUserInfoByAccount(account);
        if (Objects.isNull(player)) {
            return null;
        }
        Integer watchLiveDays = userLiveHandle.getWatchLiveDays(player,startDay, endDay);
        //转换vo
        List<GmUserWatchLiveTaskDetailVo> gmUserWatchLiveTaskDetailVos = userWatchTaskList.stream().map(userWatchTask -> {
            GmUserWatchLiveTaskDetailVo gmUserWatchLiveTaskDetailVo = new GmUserWatchLiveTaskDetailVo();
            BeanUtils.copyProperties(userWatchTask, gmUserWatchLiveTaskDetailVo);
            return gmUserWatchLiveTaskDetailVo;
        }).collect(Collectors.toList());
        //任务配置表
        List<ConfigActivityTask> configActivityTasks = configActivityTaskService.getBaseMapper().selectList(null);
        List<ConfigActivityTaskVo> configActivityTaskVos = configActivityTasks.stream().map(configActivityStart -> {
            ConfigActivityTaskVo configActivityTaskVo = new ConfigActivityTaskVo();
            BeanUtils.copyProperties(configActivityStart, configActivityTaskVo);
            return configActivityTaskVo;
        }).collect(Collectors.toList());


        GmWatchLiveConfigActivityTaskVo gmWatchLiveConfigActivityTaskVo = new GmWatchLiveConfigActivityTaskVo();
        gmWatchLiveConfigActivityTaskVo.setWatchDays(watchLiveDays);
        gmWatchLiveConfigActivityTaskVo.setGmUserWatchLiveTaskDetailVos(gmUserWatchLiveTaskDetailVos);
        gmWatchLiveConfigActivityTaskVo.setConfigActivityTaskVos(configActivityTaskVos);
        gmWatchLiveConfigActivityTaskVo.setTestCondition(userWatchTaskList.get(0).getTestCondition());
        gmWatchLiveConfigActivityTaskVo.setTestStatus(userWatchTaskList.get(0).getTestStatus());
        return gmWatchLiveConfigActivityTaskVo;
    }

    @Override
    public void updateWatchLiveTask(GmUserWatchLiveTaskDetailDto gmUserWatchLiveTaskDetailDto) {
        // 根据玄乐账号获取用户id
        LambdaQueryWrapper<DBUserLoginInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DBUserLoginInfo::getAccount, gmUserWatchLiveTaskDetailDto.getAccount());
        DBUserLoginInfo userInfo = userLoginInfoService.getOne(queryWrapper);

        // 构建更新对象
        LambdaUpdateWrapper<DBUserWatchLiveTaskDetail> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(DBUserWatchLiveTaskDetail::getUid, userInfo.getUid());

        if (gmUserWatchLiveTaskDetailDto.getType() == 0) {
            updateWrapper
                    .set(DBUserWatchLiveTaskDetail::getTestStatus, gmUserWatchLiveTaskDetailDto.getTestStatus())
                    .set(DBUserWatchLiveTaskDetail::getTestCondition, gmUserWatchLiveTaskDetailDto.getTestCondition());
        } else {
            updateWrapper
                    .set(DBUserWatchLiveTaskDetail::getTestStatus, null)
                    .set(DBUserWatchLiveTaskDetail::getTestCondition, null);
        }

        // 执行更新操作
        userWatchLiveTaskDetailMapper.update(new DBUserWatchLiveTaskDetail(), updateWrapper);
    }

    @Override
    public void resetUserFlowInfo(Integer activityId) {
        QueryWrapper<DBUserActivityInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id", activityId);
        List<DBUserActivityInfo> dbUserActivityInfos = userActivityDBService.getBaseMapper().selectList(queryWrapper);
        List<Integer> uidList = dbUserActivityInfos.stream().map(DBUserActivityInfo::getUid).collect(Collectors.toList());

        Map<Integer, ConfigStartVo> configStartMap = dataConfigStartLoader.getConfigStartMap();
        // 遍历configStartMap查找关联配置
        ConfigStartVo matchedConfig = configStartMap.values().stream()
                .filter(vo -> vo.getActivityId().equals(activityId))
                .findFirst()
                .orElse(null);

        //用户流程信息表清空当前步骤，上一步，复活步骤
        userFlowDBService.update(new DBUserFlowInfo(),
                new LambdaUpdateWrapper<DBUserFlowInfo>()
                        .in(DBUserFlowInfo::getUid, uidList)
                        .set(DBUserFlowInfo::getStepId, matchedConfig.getNext())
                        .set(DBUserFlowInfo::getPreId, null)
                        .set(DBUserFlowInfo::getReviveStepId, null)
        );
    }

}
